package com.example.ribbontest.web;


import com.example.ribbontest.command.UserCommand;
import com.example.ribbontest.domain.User;
import com.example.ribbontest.service.HelloService;
import com.example.ribbontest.service.UserService;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;


@RestController
public class HelloController {
    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    private DiscoveryClient client;

    @Autowired
    RestTemplate    restTemplate;

    @Autowired
    HelloService    helloService;

    @Autowired
    UserService     userService;


    @RequestMapping("/hello")
    public String index()
    {
        ServiceInstance instance = client.getLocalServiceInstance();
        logger.info("/hello,host:"+instance.getHost()+",service_id:"+instance.getServiceId());
        return "hello world!";
    }

    @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
    public String helloConsumer()
    {
        return restTemplate.getForEntity("http://SPRING-BOOT-TEST/hello",String.class).getBody();
    }

    @RequestMapping(value = "/users/{ids}",method = RequestMethod.GET)
    public List<User> getUsers(@PathVariable List<Integer>ids)
    {
        logger.info("call getUsers");
        return userService.getUsers(ids);
    }


    @RequestMapping(value = "/testCollapse",method = RequestMethod.GET)
    public void testCollapse()
    {
       for(int i =0;i<10;i++)
       {
          User u = userService.find(i);
          logger.info("test collapse called"+u.toString());
       }
    }

    @RequestMapping(value = "/ribbon-consumer-hystrix",method = RequestMethod.GET)
    public String helloConsumerWithHystrix()
    {
        return helloService.sayhello();

    }

    /**
     * 获取对象
     * @return
     */
    @RequestMapping(value = "/ribbon-consumer-user",method = RequestMethod.GET)
    public String helloUser()
    {
        User u = helloService.helloUser();
        return u.toString();

    }

    /**
     * 异步调用
     * @return
     */
    @RequestMapping(value = "/ribbon-consumer-asyn",method = RequestMethod.GET)
    public String helloConsumerAsyn()
    {
        Future<User> f =  helloService.helloServiceAsyn();
        User u = null;
        try {
             u = f.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return u.toString();
    }

    /**
     * 获取对象
     * @return
     */
    @RequestMapping(value = "/getUser",method = RequestMethod.GET)
    public String getUser()
    {
        User u = userService.getUser();
        return u.toString();

    }

    /**
     * 使用继承HystrixCommand的方式实现依赖调用
     * @return
     */
    @RequestMapping(value = "/getUserCommand",method = RequestMethod.GET)
    public String getUserCommand()
    {
        UserCommand userCommand = new UserCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")), restTemplate);
        //同步调用
        //Book book1 = bookCommand.execute();
        //异步调用
        Future<User> queue = userCommand.queue();
        User user = null;
        try {
            user = queue.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return user.toString();
    }

    /**
     * 缓存user
     * 换存只在当前线程有效，要初始化requestcontext
     * @param id
     * @return
     */
    @RequestMapping(value = "/getUserCache/{id}",method = RequestMethod.GET)
    @ResponseBody
    public String getUserCache(@PathVariable int id)
    {
        User u = null;
        //初始化context
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        try {
            //两个一样的command
            UserCommand userCommand1 = new UserCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")), restTemplate,id);
            UserCommand userCommand2 = new UserCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")), restTemplate,id);
            userCommand1.execute();
            u = userCommand2.execute();
        } finally {
            //关闭context
            context.shutdown();
        }
        return u.toString();

    }


    @RequestMapping(value = "/testCacheResult/{id}",method = RequestMethod.GET)
    @ResponseBody
    public String testCacheResult(@PathVariable int id)
    {

        User u = null;
        //初始化context
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        try {
            userService.getUserById(id);
            u = userService.getUserById(id);
        } finally {
            //关闭context
            context.shutdown();
        }
        return u.toString();

    }



}
